/**
 * GExporter 1.0 - Exports your gmail address book with great flexibility.
 * Copyright (C) 2005 Karthik V (karthiksden@gmail.com)
 * This software is distributed under GNU GPL ( http://www.gnu.org/copyleft/gpl.html )
 */

package vkarthik.gtools.gexport;

import java.io.*;
import java.util.ArrayList;
import javax.swing.*;

public class GExporter {

	static GMConnector con = null;
	static String prefFile = "preferences.dat";
    private static Object GMConstants;

    public static void export(GExInfo data) throws Exception {

		String nl = System.getProperty("line.separator");
		if(!login(data.user,data.password)) throw new Exception("Login failed.");
		// System.out.println("Logged in...");
		ArrayList list = getContacts(data.exportType,data.searchString,data.searchField,data.searchRule);
		// System.out.println("Got contacts...");
		BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream(data.fileLocation));

		String t = "";
		for(int i=0;i<data.exportFields.length;i++) {
			t += data.exportFields[i] + data.separator;
		}
		// // System.out.println(t);
		// System.out.println("Writing to file...");
		buf.write(t.getBytes(),0,t.length()-data.separator.length());
		buf.write(nl.getBytes(),0,nl.length());
		for(int i=0;i<list.size();i++) {
			GMContact c = (GMContact) list.get(i);
			t = "";
			if(available(data.exportFields,"name")) t += c.getName() + data.separator;
			if(available(data.exportFields,"id")) t += c.getId() + data.separator;
			if(available(data.exportFields,"email")) t += c.getEmail() + data.separator;
			if(available(data.exportFields,"notes")) t += c.getNotes() + data.separator;
			// // System.out.println(t);
			buf.write(t.getBytes(),0,t.length()-data.separator.length());
			buf.write(nl.getBytes(),0,nl.length());
			// // System.out.println(c.getName() + "," + c.getEmail());
		}
		buf.flush();
		buf.close();
		// System.out.println("Writing complete.");
	}

    public static void export(GExInfo data, ArrayList list) throws Exception {

		String nl = System.getProperty("line.separator");
		BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream(data.fileLocation));
		String t = "";
		for(int i=0;i<data.exportFields.length;i++) {
			t += data.exportFields[i] + data.separator;
		}
		// // System.out.println(t);
		// System.out.println("Writing to file...");
		buf.write(t.getBytes(),0,t.length()-data.separator.length());
		buf.write(nl.getBytes(),0,nl.length());
		for(int i=0;i<list.size();i++) {
			GMContact c = (GMContact) list.get(i);
			t = "";
			if(available(data.exportFields,"name")) t += c.getName() + data.separator;
			if(available(data.exportFields,"id")) t += c.getId() + data.separator;
			if(available(data.exportFields,"email")) t += c.getEmail() + data.separator;
			if(available(data.exportFields,"notes")) t += c.getNotes() + data.separator;
			// // System.out.println(t);
			buf.write(t.getBytes(),0,t.length()-data.separator.length());
			buf.write(nl.getBytes(),0,nl.length());
			// // System.out.println(c.getName() + "," + c.getEmail());
		}
		buf.flush();
		buf.close();
		// System.out.println("Writing complete.");
	}

	public static boolean login(String user, String pass) throws Exception {

		con = new GMConnector(user,pass,0);
		if(!con.isConnected() && !con.connect()) {
			return false;
		}
		return true;
	}

	public static ArrayList getContacts(String type, String search, String field, String rule) throws Exception {

		if(type.equalsIgnoreCase("all")) {
			return makeList(con.getContact(GMConstants.GM_CONTACT_ALL,""));
		}
		else if(type.equalsIgnoreCase("search")) {
			return makeList(con.getContact(GMConstants.GM_CONTACT_ALL,search));
		}
		else if(type.equalsIgnoreCase("custom")) {
			ArrayList list = makeList(con.getContact(GMConstants.GM_CONTACT_ALL,""));
			ArrayList newList = new ArrayList();
			int f = 0;
			if(field.equalsIgnoreCase("name")) f = 1;
			if(field.equalsIgnoreCase("id")) f = 2;
			if(field.equalsIgnoreCase("email")) f = 3;
			if(field.equalsIgnoreCase("notes")) f = 4;

			int r = 0;
			if(rule.equalsIgnoreCase("equals")) r = 1;
			if(rule.equalsIgnoreCase("startswith")) r = 2;
			if(rule.equalsIgnoreCase("endswith")) r = 3;
			if(rule.equalsIgnoreCase("contains")) r = 4;

			for(int i=0;i<list.size();i++) {
				GMContact gmc = (GMContact) list.get(i);
				if(r == 1) {
					switch(f) {
						case 1:
							if(gmc.getName().equals(search)) newList.add(gmc);
							break;
						case 2:
							if(gmc.getId().equals(search)) newList.add(gmc);
							break;
						case 3:
							if(gmc.getEmail().equals(search)) newList.add(gmc);
							break;
						case 4:
							if(gmc.getNotes().equals(search)) newList.add(gmc);
							break;

					}
				}
				if(rule.equalsIgnoreCase("startswith")) {
					switch(f) {
						case 1:
							if(gmc.getName().startsWith(search)) newList.add(gmc);
							break;
						case 2:
							if(gmc.getId().startsWith(search)) newList.add(gmc);
							break;
						case 3:
							if(gmc.getEmail().startsWith(search)) newList.add(gmc);
							break;
						case 4:
							if(gmc.getNotes().startsWith(search)) newList.add(gmc);
							break;

					}
				}
				if(rule.equalsIgnoreCase("endswith")) {
					switch(f) {
						case 1:
							if(gmc.getName().endsWith(search)) newList.add(gmc);
							break;
						case 2:
							if(gmc.getId().endsWith(search)) newList.add(gmc);
							break;
						case 3:
							if(gmc.getEmail().endsWith(search)) newList.add(gmc);
							break;
						case 4:
							if(gmc.getNotes().endsWith(search)) newList.add(gmc);
							break;

					}
				}
				if(rule.equalsIgnoreCase("contains")) {
					switch(f) {
						case 1:
							if(gmc.getName().indexOf(search) >= 0) newList.add(gmc);
							break;
						case 2:
							if(gmc.getId().indexOf(search) >= 0) newList.add(gmc);
							break;
						case 3:
							if(gmc.getEmail().indexOf(search) >= 0) newList.add(gmc);
							break;
						case 4:
							if(gmc.getNotes().indexOf(search) >= 0) newList.add(gmc);
							break;

					}
				}
			}
			return newList;
		}
		return null;
	}

	public static boolean available(String[] ar, String search) {

		for(int i=0;i<ar.length;i++) {
			if(search.equalsIgnoreCase(ar[i])) return true;
		}
		// // System.out.println("Field " + search + " was not found.");
		return false;
	}

	public static void savePreferences(GExInfo data) {

		try {
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(prefFile));
			out.writeObject(data);
			out.flush();
			out.close();
		} catch(Exception x) {
			// System.out.println(x);
		}
	}

	public static GExInfo getPreferences() {

		try {
			ObjectInputStream in = new ObjectInputStream(new FileInputStream(prefFile));
			GExInfo data = (GExInfo) in.readObject();
			in.close();
			return data;
		} catch(Exception x) {
			// System.out.println(x);
		}
		return null;
	}

    public static void main(String[] ar) throws Exception {

		GExInfo data = null;
    	GExView view = new GExView();
    	GExProgressView pd = new GExProgressView(view);

		while(true) {
		try {
		data = getPreferences();
    	view.initValues(data);
    	pd.hide();
    	pd.progress.setMinimum(0);
    	pd.progress.setMaximum(100);
    	pd.lProgress.setText("Starting Export...");

    	data = null;
    	while(data == null) {
			data = view.getExportData();
			try {
				Thread.sleep(100);
			} catch(Exception x) {

			}
		}
    	// System.out.println("Printing ex data");
    	// System.out.println(data);
    	// System.out.println("Saving Preferences...");
    	savePreferences(data);

		pd.show();
		pd.lProgress.setText("Logging in...");
		pd.progress.setValue(0);
		if(!login(data.user,data.password)) throw new Exception("Login failed.");
    	pd.progress.setValue(30);
    	pd.lProgress.setText("Logged in...");

		pd.lProgress.setText("Fetching contact list...");
		ArrayList list = getContacts(data.exportType,data.searchString,data.searchField,data.searchRule);
    	pd.progress.setValue(70);
    	pd.lProgress.setText("Contact list fetched...");

		pd.lProgress.setText("Exporting to file...");
    	export(data,list);
    	pd.lProgress.setText("Finished Export.");
    	pd.progress.setValue(100);
    	// view.dispose();
    	pd.hide();
    	// System.exit(0);
		} catch(Exception x) {
			JOptionPane.showMessageDialog(view, x, "Error", JOptionPane.ERROR_MESSAGE);
		}
		}
    }

    private static ArrayList makeList(GMContact[] contacts) {

		if(contacts == null) return null;
		ArrayList list = new ArrayList();
		for(int i=0;i<contacts.length;i++) {
			list.add(contacts[i]);
		}
		return list;
	}
}